1
2
3
4
5
6
7 package io.vavr.collection;
8
9 import io.vavr.Tuple;
10 import io.vavr.Tuple2;
11 import io.vavr.Tuple3;
12 import io.vavr.collection.RedBlackTreeModule.Empty;
13 import io.vavr.collection.RedBlackTreeModule.Node;
14 import io.vavr.control.Option;
15
16 import java.io.Serializable;
17 import java.util.Comparator;
18 import java.util.NoSuchElementException;
19 import java.util.Objects;
20
21 import static io.vavr.collection.RedBlackTree.Color.BLACK;
22 import static io.vavr.collection.RedBlackTree.Color.RED;
23
24
25
26
27
28
29
30
31
32
33
34
35
36 interface RedBlackTree<T> extends Iterable<T> {
37
38 static <T extends Comparable<? super T>> RedBlackTree<T> empty() {
39 return new Empty<>(Comparators.naturalComparator());
40 }
41
42 static <T> RedBlackTree<T> empty(Comparator<? super T> comparator) {
43 Objects.requireNonNull(comparator, "comparator is null");
44 return new Empty<>(comparator);
45 }
46
47 static <T extends Comparable<? super T>> RedBlackTree<T> of(T value) {
48 return of(Comparators.naturalComparator(), value);
49 }
50
51 static <T> RedBlackTree<T> of(Comparator<? super T> comparator, T value) {
52 Objects.requireNonNull(comparator, "comparator is null");
53 final Empty<T> empty = new Empty<>(comparator);
54 return new Node<>(BLACK, 1, empty, value, empty, empty);
55 }
56
57 @SuppressWarnings("varargs")
58 @SafeVarargs
59 static <T extends Comparable<? super T>> RedBlackTree<T> of(T... values) {
60 Objects.requireNonNull(values, "values is null");
61 return of(Comparators.<T> naturalComparator(), values);
62 }
63
64 @SafeVarargs
65 static <T> RedBlackTree<T> of(Comparator<? super T> comparator, T... values) {
66 Objects.requireNonNull(comparator, "comparator is null");
67 Objects.requireNonNull(values, "values is null");
68 RedBlackTree<T> tree = empty(comparator);
69 for (T value : values) {
70 tree = tree.insert(value);
71 }
72 return tree;
73 }
74
75 static <T extends Comparable<? super T>> RedBlackTree<T> ofAll(Iterable<? extends T> values) {
76 Objects.requireNonNull(values, "values is null");
77 return ofAll(Comparators.naturalComparator(), values);
78 }
79
80 @SuppressWarnings("unchecked")
81 static <T> RedBlackTree<T> ofAll(Comparator<? super T> comparator, Iterable<? extends T> values) {
82 Objects.requireNonNull(comparator, "comparator is null");
83 Objects.requireNonNull(values, "values is null");
84
85 if (values instanceof RedBlackTree && ((RedBlackTree<T>) values).comparator() == comparator) {
86 return (RedBlackTree<T>) values;
87 } else {
88 RedBlackTree<T> tree = empty(comparator);
89 for (T value : values) {
90 tree = tree.insert(value);
91 }
92 return tree;
93 }
94 }
95
96
97
98
99
100
101
102 default RedBlackTree<T> insert(T value) {
103 return Node.insert(this, value).color(BLACK);
104 }
105
106
107
108
109
110
111
112
113 Color color();
114
115
116
117
118
119
120 Comparator<T> comparator();
121
122
123
124
125
126
127
128 boolean contains(T value);
129
130
131
132
133
134
135
136 default RedBlackTree<T> delete(T value) {
137 final RedBlackTree<T> tree = Node.delete(this, value)._1;
138 return Node.color(tree, BLACK);
139 }
140
141 default RedBlackTree<T> difference(RedBlackTree<T> tree) {
142 Objects.requireNonNull(tree, "tree is null");
143 if (isEmpty() || tree.isEmpty()) {
144 return this;
145 } else {
146 final Node<T> that = (Node<T>) tree;
147 final Tuple2<RedBlackTree<T>, RedBlackTree<T>> split = Node.split(this, that.value);
148 return Node.merge(split._1.difference(that.left), split._2.difference(that.right));
149 }
150 }
151
152
153
154
155
156
157 RedBlackTree<T> emptyInstance();
158
159
160
161
162
163
164
165
166
167
168
169 Option<T> find(T value);
170
171 default RedBlackTree<T> intersection(RedBlackTree<T> tree) {
172 Objects.requireNonNull(tree, "tree is null");
173 if (isEmpty()) {
174 return this;
175 } else if (tree.isEmpty()) {
176 return tree;
177 } else {
178 final Node<T> that = (Node<T>) tree;
179 final Tuple2<RedBlackTree<T>, RedBlackTree<T>> split = Node.split(this, that.value);
180 if (contains(that.value)) {
181 return Node.join(split._1.intersection(that.left), that.value, split._2.intersection(that.right));
182 } else {
183 return Node.merge(split._1.intersection(that.left), split._2.intersection(that.right));
184 }
185 }
186 }
187
188
189
190
191
192
193 boolean isEmpty();
194
195
196
197
198
199
200
201 RedBlackTree<T> left();
202
203
204
205
206
207
208 default Option<T> max() {
209 return isEmpty() ? Option.none() : Option.some(Node.maximum((Node<T>) this));
210 }
211
212
213
214
215
216
217 default Option<T> min() {
218 return isEmpty() ? Option.none() : Option.some(Node.minimum((Node<T>) this));
219 }
220
221
222
223
224
225
226
227 RedBlackTree<T> right();
228
229
230
231
232
233
234 int size();
235
236
237
238
239
240
241
242 default RedBlackTree<T> union(RedBlackTree<T> tree) {
243 Objects.requireNonNull(tree, "tree is null");
244 if (tree.isEmpty()) {
245 return this;
246 } else {
247 final Node<T> that = (Node<T>) tree;
248 if (isEmpty()) {
249 return that.color(BLACK);
250 } else {
251 final Tuple2<RedBlackTree<T>, RedBlackTree<T>> split = Node.split(this, that.value);
252 return Node.join(split._1.union(that.left), that.value, split._2.union(that.right));
253 }
254 }
255 }
256
257
258
259
260
261
262
263 T value();
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284 @Override
285 default Iterator<T> iterator() {
286 if (isEmpty()) {
287 return Iterator.empty();
288 } else {
289 final Node<T> that = (Node<T>) this;
290 return new AbstractIterator<T>() {
291
292 List<Node<T>> stack = pushLeftChildren(List.empty(), that);
293
294 @Override
295 public boolean hasNext() {
296 return !stack.isEmpty();
297 }
298
299 @Override
300 public T getNext() {
301 final Tuple2<Node<T>, ? extends List<Node<T>>> result = stack.pop2();
302 final Node<T> node = result._1;
303 stack = node.right.isEmpty() ? result._2 : pushLeftChildren(result._2, (Node<T>) node.right);
304 return result._1.value;
305 }
306
307 private List<Node<T>> pushLeftChildren(List<Node<T>> initialStack, Node<T> that) {
308 List<Node<T>> stack = initialStack;
309 RedBlackTree<T> tree = that;
310 while (!tree.isEmpty()) {
311 final Node<T> node = (Node<T>) tree;
312 stack = stack.push(node);
313 tree = node.left;
314 }
315 return stack;
316 }
317 };
318 }
319 }
320
321
322
323
324
325
326 @Override
327 boolean equals(Object o);
328
329
330
331
332
333
334 @Override
335 int hashCode();
336
337
338
339
340
341
342 @Override
343 String toString();
344
345 enum Color {
346
347 RED, BLACK;
348
349 @Override
350 public String toString() {
351 return (this == RED) ? "R" : "B";
352 }
353 }
354 }
355
356 interface RedBlackTreeModule {
357
358
359
360
361
362
363 final class Node<T> implements RedBlackTree<T>, Serializable {
364
365 private static final long serialVersionUID = 1L;
366
367 final Color color;
368 final int blackHeight;
369 final RedBlackTree<T> left;
370 final T value;
371 final RedBlackTree<T> right;
372 final Empty<T> empty;
373 final int size;
374
375
376 Node(Color color, int blackHeight, RedBlackTree<T> left, T value, RedBlackTree<T> right, Empty<T> empty) {
377 this.color = color;
378 this.blackHeight = blackHeight;
379 this.left = left;
380 this.value = value;
381 this.right = right;
382 this.empty = empty;
383 this.size = left.size() + right.size() + 1;
384 }
385
386 @Override
387 public Color color() {
388 return color;
389 }
390
391 @Override
392 public Comparator<T> comparator() {
393 return empty.comparator;
394 }
395
396 @Override
397 public boolean contains(T value) {
398 final int result = empty.comparator.compare(value, this.value);
399 if (result < 0) {
400 return left.contains(value);
401 } else if (result > 0) {
402 return right.contains(value);
403 } else {
404 return true;
405 }
406 }
407
408 @Override
409 public Empty<T> emptyInstance() {
410 return empty;
411 }
412
413 @Override
414 public Option<T> find(T value) {
415 final int result = empty.comparator.compare(value, this.value);
416 if (result < 0) {
417 return left.find(value);
418 } else if (result > 0) {
419 return right.find(value);
420 } else {
421 return Option.some(this.value);
422 }
423 }
424
425 @Override
426 public boolean isEmpty() {
427 return false;
428 }
429
430 @Override
431 public RedBlackTree<T> left() {
432 return left;
433 }
434
435 @Override
436 public RedBlackTree<T> right() {
437 return right;
438 }
439
440 @Override
441 public int size() {
442 return size;
443 }
444
445 @Override
446 public T value() {
447 return value;
448 }
449
450 @Override
451 public boolean equals(Object o) {
452 if (o == this) {
453 return true;
454 } else if (o instanceof Node) {
455 final Node<?> that = (Node<?>) o;
456 return Collections.areEqual(this, that);
457 } else {
458 return false;
459 }
460 }
461
462 @Override
463 public int hashCode() {
464
465
466 return Collections.hashOrdered(this);
467 }
468
469 @Override
470 public String toString() {
471 return isLeaf() ? "(" + color + ":" + value + ")" : toLispString(this);
472 }
473
474 private static String toLispString(RedBlackTree<?> tree) {
475 if (tree.isEmpty()) {
476 return "";
477 } else {
478 final Node<?> node = (Node<?>) tree;
479 final String value = node.color + ":" + node.value;
480 if (node.isLeaf()) {
481 return value;
482 } else {
483 final String left = node.left.isEmpty() ? "" : " " + toLispString(node.left);
484 final String right = node.right.isEmpty() ? "" : " " + toLispString(node.right);
485 return "(" + value + left + right + ")";
486 }
487 }
488 }
489
490 private boolean isLeaf() {
491 return left.isEmpty() && right.isEmpty();
492 }
493
494 Node<T> color(Color color) {
495 return (this.color == color) ? this : new Node<>(color, blackHeight, left, value, right, empty);
496 }
497
498 static <T> RedBlackTree<T> color(RedBlackTree<T> tree, Color color) {
499 return tree.isEmpty() ? tree : ((Node<T>) tree).color(color);
500 }
501
502 private static <T> Node<T> balanceLeft(Color color, int blackHeight, RedBlackTree<T> left, T value,
503 RedBlackTree<T> right, Empty<T> empty) {
504 if (color == BLACK) {
505 if (!left.isEmpty()) {
506 final Node<T> ln = (Node<T>) left;
507 if (ln.color == RED) {
508 if (!ln.left.isEmpty()) {
509 final Node<T> lln = (Node<T>) ln.left;
510 if (lln.color == RED) {
511 final Node<T> newLeft = new Node<>(BLACK, blackHeight, lln.left, lln.value, lln.right,
512 empty);
513 final Node<T> newRight = new Node<>(BLACK, blackHeight, ln.right, value, right, empty);
514 return new Node<>(RED, blackHeight + 1, newLeft, ln.value, newRight, empty);
515 }
516 }
517 if (!ln.right.isEmpty()) {
518 final Node<T> lrn = (Node<T>) ln.right;
519 if (lrn.color == RED) {
520 final Node<T> newLeft = new Node<>(BLACK, blackHeight, ln.left, ln.value, lrn.left,
521 empty);
522 final Node<T> newRight = new Node<>(BLACK, blackHeight, lrn.right, value, right, empty);
523 return new Node<>(RED, blackHeight + 1, newLeft, lrn.value, newRight, empty);
524 }
525 }
526 }
527 }
528 }
529 return new Node<>(color, blackHeight, left, value, right, empty);
530 }
531
532 private static <T> Node<T> balanceRight(Color color, int blackHeight, RedBlackTree<T> left, T value,
533 RedBlackTree<T> right, Empty<T> empty) {
534 if (color == BLACK) {
535 if (!right.isEmpty()) {
536 final Node<T> rn = (Node<T>) right;
537 if (rn.color == RED) {
538 if (!rn.right.isEmpty()) {
539 final Node<T> rrn = (Node<T>) rn.right;
540 if (rrn.color == RED) {
541 final Node<T> newLeft = new Node<>(BLACK, blackHeight, left, value, rn.left, empty);
542 final Node<T> newRight = new Node<>(BLACK, blackHeight, rrn.left, rrn.value, rrn.right,
543 empty);
544 return new Node<>(RED, blackHeight + 1, newLeft, rn.value, newRight, empty);
545 }
546 }
547 if (!rn.left.isEmpty()) {
548 final Node<T> rln = (Node<T>) rn.left;
549 if (rln.color == RED) {
550 final Node<T> newLeft = new Node<>(BLACK, blackHeight, left, value, rln.left, empty);
551 final Node<T> newRight = new Node<>(BLACK, blackHeight, rln.right, rn.value, rn.right,
552 empty);
553 return new Node<>(RED, blackHeight + 1, newLeft, rln.value, newRight, empty);
554 }
555 }
556 }
557 }
558 }
559 return new Node<>(color, blackHeight, left, value, right, empty);
560 }
561
562 private static <T> Tuple2<? extends RedBlackTree<T>, Boolean> blackify(RedBlackTree<T> tree) {
563 if (tree instanceof Node) {
564 final Node<T> node = (Node<T>) tree;
565 if (node.color == RED) {
566 return Tuple.of(node.color(BLACK), false);
567 }
568 }
569 return Tuple.of(tree, true);
570 }
571
572 static <T> Tuple2<? extends RedBlackTree<T>, Boolean> delete(RedBlackTree<T> tree, T value) {
573 if (tree.isEmpty()) {
574 return Tuple.of(tree, false);
575 } else {
576 final Node<T> node = (Node<T>) tree;
577 final int comparison = node.comparator().compare(value, node.value);
578 if (comparison < 0) {
579 final Tuple2<? extends RedBlackTree<T>, Boolean> deleted = delete(node.left, value);
580 final RedBlackTree<T> l = deleted._1;
581 final boolean d = deleted._2;
582 if (d) {
583 return Node.unbalancedRight(node.color, node.blackHeight - 1, l, node.value, node.right,
584 node.empty);
585 } else {
586 final Node<T> newNode = new Node<>(node.color, node.blackHeight, l, node.value, node.right,
587 node.empty);
588 return Tuple.of(newNode, false);
589 }
590 } else if (comparison > 0) {
591 final Tuple2<? extends RedBlackTree<T>, Boolean> deleted = delete(node.right, value);
592 final RedBlackTree<T> r = deleted._1;
593 final boolean d = deleted._2;
594 if (d) {
595 return Node.unbalancedLeft(node.color, node.blackHeight - 1, node.left, node.value, r,
596 node.empty);
597 } else {
598 final Node<T> newNode = new Node<>(node.color, node.blackHeight, node.left, node.value, r,
599 node.empty);
600 return Tuple.of(newNode, false);
601 }
602 } else {
603 if (node.right.isEmpty()) {
604 if (node.color == BLACK) {
605 return blackify(node.left);
606 } else {
607 return Tuple.of(node.left, false);
608 }
609 } else {
610 final Node<T> nodeRight = (Node<T>) node.right;
611 final Tuple3<? extends RedBlackTree<T>, Boolean, T> newRight = deleteMin(nodeRight);
612 final RedBlackTree<T> r = newRight._1;
613 final boolean d = newRight._2;
614 final T m = newRight._3;
615 if (d) {
616 return Node.unbalancedLeft(node.color, node.blackHeight - 1, node.left, m, r, node.empty);
617 } else {
618 final RedBlackTree<T> newNode = new Node<>(node.color, node.blackHeight, node.left, m, r,
619 node.empty);
620 return Tuple.of(newNode, false);
621 }
622 }
623 }
624 }
625 }
626
627 private static <T> Tuple3<? extends RedBlackTree<T>, Boolean, T> deleteMin(Node<T> node) {
628 if (node.left.isEmpty()) {
629 if (node.color == BLACK) {
630 if (node.right.isEmpty()) {
631 return Tuple.of(node.empty, true, node.value);
632 } else {
633 final Node<T> rightNode = (Node<T>) node.right;
634 return Tuple.of(rightNode.color(BLACK), false, node.value);
635 }
636 } else {
637 return Tuple.of(node.right, false, node.value);
638 }
639 } else {
640 final Node<T> nodeLeft = (Node<T>) node.left;
641 final Tuple3<? extends RedBlackTree<T>, Boolean, T> newNode = deleteMin(nodeLeft);
642 final RedBlackTree<T> l = newNode._1;
643 final boolean d = newNode._2;
644 final T m = newNode._3;
645 if (d) {
646 final Tuple2<Node<T>, Boolean> tD = Node.unbalancedRight(node.color, node.blackHeight - 1, l,
647 node.value, node.right, node.empty);
648 return Tuple.of(tD._1, tD._2, m);
649 } else {
650 final Node<T> tD = new Node<>(node.color, node.blackHeight, l, node.value, node.right, node.empty);
651 return Tuple.of(tD, false, m);
652 }
653 }
654 }
655
656 static <T> Node<T> insert(RedBlackTree<T> tree, T value) {
657 if (tree.isEmpty()) {
658 final Empty<T> empty = (Empty<T>) tree;
659 return new Node<>(RED, 1, empty, value, empty, empty);
660 } else {
661 final Node<T> node = (Node<T>) tree;
662 final int comparison = node.comparator().compare(value, node.value);
663 if (comparison < 0) {
664 final Node<T> newLeft = insert(node.left, value);
665 return (newLeft == node.left)
666 ? node
667 : Node.balanceLeft(node.color, node.blackHeight, newLeft, node.value, node.right,
668 node.empty);
669 } else if (comparison > 0) {
670 final Node<T> newRight = insert(node.right, value);
671 return (newRight == node.right)
672 ? node
673 : Node.balanceRight(node.color, node.blackHeight, node.left, node.value, newRight,
674 node.empty);
675 } else {
676
677
678 return new Node<>(node.color, node.blackHeight, node.left, value, node.right, node.empty);
679 }
680 }
681 }
682
683 private static boolean isRed(RedBlackTree<?> tree) {
684 return !tree.isEmpty() && ((Node<?>) tree).color == RED;
685 }
686
687 static <T> RedBlackTree<T> join(RedBlackTree<T> t1, T value, RedBlackTree<T> t2) {
688 if (t1.isEmpty()) {
689 return t2.insert(value);
690 } else if (t2.isEmpty()) {
691 return t1.insert(value);
692 } else {
693 final Node<T> n1 = (Node<T>) t1;
694 final Node<T> n2 = (Node<T>) t2;
695 final int comparison = n1.blackHeight - n2.blackHeight;
696 if (comparison < 0) {
697 return Node.joinLT(n1, value, n2, n1.blackHeight).color(BLACK);
698 } else if (comparison > 0) {
699 return Node.joinGT(n1, value, n2, n2.blackHeight).color(BLACK);
700 } else {
701 return new Node<>(BLACK, n1.blackHeight + 1, n1, value, n2, n1.empty);
702 }
703 }
704 }
705
706 private static <T> Node<T> joinGT(Node<T> n1, T value, Node<T> n2, int h2) {
707 if (n1.blackHeight == h2) {
708 return new Node<>(RED, h2 + 1, n1, value, n2, n1.empty);
709 } else {
710 final Node<T> node = joinGT((Node<T>) n1.right, value, n2, h2);
711 return Node.balanceRight(n1.color, n1.blackHeight, n1.left, n1.value, node, n2.empty);
712 }
713 }
714
715 private static <T> Node<T> joinLT(Node<T> n1, T value, Node<T> n2, int h1) {
716 if (n2.blackHeight == h1) {
717 return new Node<>(RED, h1 + 1, n1, value, n2, n1.empty);
718 } else {
719 final Node<T> node = joinLT(n1, value, (Node<T>) n2.left, h1);
720 return Node.balanceLeft(n2.color, n2.blackHeight, node, n2.value, n2.right, n2.empty);
721 }
722 }
723
724 static <T> RedBlackTree<T> merge(RedBlackTree<T> t1, RedBlackTree<T> t2) {
725 if (t1.isEmpty()) {
726 return t2;
727 } else if (t2.isEmpty()) {
728 return t1;
729 } else {
730 final Node<T> n1 = (Node<T>) t1;
731 final Node<T> n2 = (Node<T>) t2;
732 final int comparison = n1.blackHeight - n2.blackHeight;
733 if (comparison < 0) {
734 final Node<T> node = Node.mergeLT(n1, n2, n1.blackHeight);
735 return Node.color(node, BLACK);
736 } else if (comparison > 0) {
737 final Node<T> node = Node.mergeGT(n1, n2, n2.blackHeight);
738 return Node.color(node, BLACK);
739 } else {
740 final Node<T> node = Node.mergeEQ(n1, n2);
741 return Node.color(node, BLACK);
742 }
743 }
744 }
745
746 private static <T> Node<T> mergeEQ(Node<T> n1, Node<T> n2) {
747 final T m = Node.minimum(n2);
748 final RedBlackTree<T> t2 = Node.deleteMin(n2)._1;
749 final int h2 = t2.isEmpty() ? 0 : ((Node<T>) t2).blackHeight;
750 if (n1.blackHeight == h2) {
751 return new Node<>(RED, n1.blackHeight + 1, n1, m, t2, n1.empty);
752 } else if (isRed(n1.left)) {
753 final Node<T> node = new Node<>(BLACK, n1.blackHeight, n1.right, m, t2, n1.empty);
754 return new Node<>(RED, n1.blackHeight, Node.color(n1.left, BLACK), n1.value, node, n1.empty);
755 } else if (isRed(n1.right)) {
756 final RedBlackTree<T> rl = ((Node<T>) n1.right).left;
757 final T rx = ((Node<T>) n1.right).value;
758 final RedBlackTree<T> rr = ((Node<T>) n1.right).right;
759 final Node<T> left = new Node<>(RED, n1.blackHeight, n1.left, n1.value, rl, n1.empty);
760 final Node<T> right = new Node<>(RED, n1.blackHeight, rr, m, t2, n1.empty);
761 return new Node<>(BLACK, n1.blackHeight, left, rx, right, n1.empty);
762 } else {
763 return new Node<>(BLACK, n1.blackHeight, n1.color(RED), m, t2, n1.empty);
764 }
765 }
766
767 private static <T> Node<T> mergeGT(Node<T> n1, Node<T> n2, int h2) {
768 if (n1.blackHeight == h2) {
769 return Node.mergeEQ(n1, n2);
770 } else {
771 final Node<T> node = Node.mergeGT((Node<T>) n1.right, n2, h2);
772 return Node.balanceRight(n1.color, n1.blackHeight, n1.left, n1.value, node, n1.empty);
773 }
774 }
775
776 private static <T> Node<T> mergeLT(Node<T> n1, Node<T> n2, int h1) {
777 if (n2.blackHeight == h1) {
778 return Node.mergeEQ(n1, n2);
779 } else {
780 final Node<T> node = Node.mergeLT(n1, (Node<T>) n2.left, h1);
781 return Node.balanceLeft(n2.color, n2.blackHeight, node, n2.value, n2.right, n2.empty);
782 }
783 }
784
785 static <T> T maximum(Node<T> node) {
786 Node<T> curr = node;
787 while (!curr.right.isEmpty()) {
788 curr = (Node<T>) curr.right;
789 }
790 return curr.value;
791 }
792
793 static <T> T minimum(Node<T> node) {
794 Node<T> curr = node;
795 while (!curr.left.isEmpty()) {
796 curr = (Node<T>) curr.left;
797 }
798 return curr.value;
799 }
800
801 static <T> Tuple2<RedBlackTree<T>, RedBlackTree<T>> split(RedBlackTree<T> tree, T value) {
802 if (tree.isEmpty()) {
803 return Tuple.of(tree, tree);
804 } else {
805 final Node<T> node = (Node<T>) tree;
806 final int comparison = node.comparator().compare(value, node.value);
807 if (comparison < 0) {
808 final Tuple2<RedBlackTree<T>, RedBlackTree<T>> split = Node.split(node.left, value);
809 return Tuple.of(split._1, Node.join(split._2, node.value, Node.color(node.right, BLACK)));
810 } else if (comparison > 0) {
811 final Tuple2<RedBlackTree<T>, RedBlackTree<T>> split = Node.split(node.right, value);
812 return Tuple.of(Node.join(Node.color(node.left, BLACK), node.value, split._1), split._2);
813 } else {
814 return Tuple.of(Node.color(node.left, BLACK), Node.color(node.right, BLACK));
815 }
816 }
817 }
818
819 private static <T> Tuple2<Node<T>, Boolean> unbalancedLeft(Color color, int blackHeight, RedBlackTree<T> left,
820 T value, RedBlackTree<T> right, Empty<T> empty) {
821 if (!left.isEmpty()) {
822 final Node<T> ln = (Node<T>) left;
823 if (ln.color == BLACK) {
824 final Node<T> newNode = Node.balanceLeft(BLACK, blackHeight, ln.color(RED), value, right, empty);
825 return Tuple.of(newNode, color == BLACK);
826 } else if (color == BLACK && !ln.right.isEmpty()) {
827 final Node<T> lrn = (Node<T>) ln.right;
828 if (lrn.color == BLACK) {
829 final Node<T> newRightNode = Node.balanceLeft(BLACK, blackHeight, lrn.color(RED), value, right,
830 empty);
831 final Node<T> newNode = new Node<>(BLACK, ln.blackHeight, ln.left, ln.value, newRightNode,
832 empty);
833 return Tuple.of(newNode, false);
834 }
835 }
836 }
837 throw new IllegalStateException("unbalancedLeft(" + color + ", " + blackHeight + ", " + left + ", " + value + ", " + right + ")");
838 }
839
840 private static <T> Tuple2<Node<T>, Boolean> unbalancedRight(Color color, int blackHeight, RedBlackTree<T> left,
841 T value, RedBlackTree<T> right, Empty<T> empty) {
842 if (!right.isEmpty()) {
843 final Node<T> rn = (Node<T>) right;
844 if (rn.color == BLACK) {
845 final Node<T> newNode = Node.balanceRight(BLACK, blackHeight, left, value, rn.color(RED), empty);
846 return Tuple.of(newNode, color == BLACK);
847 } else if (color == BLACK && !rn.left.isEmpty()) {
848 final Node<T> rln = (Node<T>) rn.left;
849 if (rln.color == BLACK) {
850 final Node<T> newLeftNode = Node.balanceRight(BLACK, blackHeight, left, value, rln.color(RED),
851 empty);
852 final Node<T> newNode = new Node<>(BLACK, rn.blackHeight, newLeftNode, rn.value, rn.right,
853 empty);
854 return Tuple.of(newNode, false);
855 }
856 }
857 }
858 throw new IllegalStateException("unbalancedRight(" + color + ", " + blackHeight + ", " + left + ", " + value + ", " + right + ")");
859 }
860 }
861
862
863
864
865
866
867 final class Empty<T> implements RedBlackTree<T>, Serializable {
868
869 private static final long serialVersionUID = 1L;
870
871 final Comparator<T> comparator;
872
873
874 @SuppressWarnings("unchecked")
875 Empty(Comparator<? super T> comparator) {
876 this.comparator = (Comparator<T>) comparator;
877 }
878
879 @Override
880 public Color color() {
881 return BLACK;
882 }
883
884 @Override
885 public Comparator<T> comparator() {
886 return comparator;
887 }
888
889 @Override
890 public boolean contains(T value) {
891 return false;
892 }
893
894 @Override
895 public Empty<T> emptyInstance() {
896 return this;
897 }
898
899 @Override
900 public Option<T> find(T value) {
901 return Option.none();
902 }
903
904 @Override
905 public boolean isEmpty() {
906 return true;
907 }
908
909 @Override
910 public RedBlackTree<T> left() {
911 throw new UnsupportedOperationException("left on empty");
912 }
913
914 @Override
915 public RedBlackTree<T> right() {
916 throw new UnsupportedOperationException("right on empty");
917 }
918
919 @Override
920 public int size() {
921 return 0;
922 }
923
924 @Override
925 public T value() {
926 throw new NoSuchElementException("value on empty");
927 }
928
929 @Override
930 public boolean equals(Object o) {
931
932 return (o == this) || (o instanceof Empty);
933 }
934
935 @Override
936 public int hashCode() {
937 return 1;
938 }
939
940 @Override
941 public String toString() {
942 return "()";
943 }
944 }
945 }